<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>系统权限 | Turbo Cloud</title>
    <meta name="generator" content="VuePress 1.9.7">
    <link rel="icon" href="/turbo-cloud-blog/assets/img/favicon.ico">
    <meta name="description" content="Turbo Cloud 官方文档">
    <meta name="keywords" content="Turbo Cloud">
    <meta name="theme-color" content="#1890ff">
    
    <link rel="preload" href="/turbo-cloud-blog/assets/css/0.styles.381a30c5.css" as="style"><link rel="preload" href="/turbo-cloud-blog/assets/js/app.fa1a75e5.js" as="script"><link rel="preload" href="/turbo-cloud-blog/assets/js/2.5e61b679.js" as="script"><link rel="preload" href="/turbo-cloud-blog/assets/js/9.47d98ce3.js" as="script"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/10.7b8376a1.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/11.602e2a63.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/12.e733c92a.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/13.0f5f7f7c.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/3.21ac3373.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/4.94346478.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/5.5a5b15d6.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/6.9d47cb7a.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/7.5a12dc76.js"><link rel="prefetch" href="/turbo-cloud-blog/assets/js/8.a23eef87.js">
    <link rel="stylesheet" href="/turbo-cloud-blog/assets/css/0.styles.381a30c5.css">
  </head>
  <body class="theme-mode-light">
    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/turbo-cloud-blog/" class="home-link router-link-active"><img src="/turbo-cloud-blog/assets/img/logo.svg" alt="Turbo Cloud" class="logo"> <span class="site-name can-hide">Turbo Cloud</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/turbo-cloud-blog/" class="nav-link">首页</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="指南" class="dropdown-title"><a href="/turbo-cloud-blog/pages/24112f/" class="link-title">指南</a> <span class="title" style="display:none;">指南</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/turbo-cloud-blog/pages/24112f/" class="nav-link">快速入门</a></li></ul></div></div><div class="nav-item"><a href="/turbo-cloud-blog/pages/f84a74/" class="nav-link">问答</a></div><div class="nav-item"><a href="/turbo-cloud-blog/pages/4fedc2/" class="nav-link">💖支持</a></div><div class="nav-item"><a href="/turbo-cloud-blog/pages/4fabc2/" class="nav-link">更新日志</a></div> <a href="https://gitee.com/aquarian-bottle" target="_blank" rel="noopener noreferrer" class="repo-link">
    Gitee
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><!----> <nav class="nav-links"><div class="nav-item"><a href="/turbo-cloud-blog/" class="nav-link">首页</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="指南" class="dropdown-title"><a href="/turbo-cloud-blog/pages/24112f/" class="link-title">指南</a> <span class="title" style="display:none;">指南</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/turbo-cloud-blog/pages/24112f/" class="nav-link">快速入门</a></li></ul></div></div><div class="nav-item"><a href="/turbo-cloud-blog/pages/f84a74/" class="nav-link">问答</a></div><div class="nav-item"><a href="/turbo-cloud-blog/pages/4fedc2/" class="nav-link">💖支持</a></div><div class="nav-item"><a href="/turbo-cloud-blog/pages/4fabc2/" class="nav-link">更新日志</a></div> <a href="https://gitee.com/aquarian-bottle" target="_blank" rel="noopener noreferrer" class="repo-link">
    Gitee
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <div class="sidebar-slot sidebar-slot-top">
    
  </div> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>快速入门</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/turbo-cloud-blog/pages/24112f/" class="sidebar-link">简介</a></li><li><a href="/turbo-cloud-blog/pages/226c21/" class="sidebar-link">快速开始</a></li><li><a href="/turbo-cloud-blog/pages/bab2db/" class="sidebar-link">系统登录</a></li><li><a href="/turbo-cloud-blog/pages/3b5af0/" aria-current="page" class="active sidebar-link">系统权限</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/turbo-cloud-blog/pages/3b5af0/#系统权限图" class="sidebar-link">系统权限图</a></li><li class="sidebar-sub-header level2"><a href="/turbo-cloud-blog/pages/3b5af0/#用户角色设计" class="sidebar-link">用户角色设计</a></li><li class="sidebar-sub-header level2"><a href="/turbo-cloud-blog/pages/3b5af0/#接口权限设计" class="sidebar-link">接口权限设计</a></li><li class="sidebar-sub-header level2"><a href="/turbo-cloud-blog/pages/3b5af0/#数据库表" class="sidebar-link">数据库表</a></li><li class="sidebar-sub-header level2"><a href="/turbo-cloud-blog/pages/3b5af0/#数据库表关系模型" class="sidebar-link">数据库表关系模型</a></li><li class="sidebar-sub-header level2"><a href="/turbo-cloud-blog/pages/3b5af0/#数据库脚本" class="sidebar-link">数据库脚本</a></li></ul></li></ul></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="placeholder"></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="">系统权限<!----></h1> <div class="page-slot page-slot-top">
    <style>
      .page-wwads{
        width:100%!important;
        min-height: 0;
        margin: 0;
      }
      .page-wwads .wwads-img img{
        width:80px!important;
      }
      .page-wwads .wwads-poweredby{
        width: 40px;
        position: absolute;
        right: 25px;
        bottom: 3px;
      }
      .wwads-content .wwads-text, .page-wwads .wwads-text{
        height: 100%;
        padding-top: 5px;
        display: block;
      }
    </style>
  </div> <div class="theme-vdoing-content content__default"><p><code>Turbo Cloud</code>的<code>UMS</code>（User Manger System）服务模块包含了：系统的用户管理、菜单、角色、岗位、修改密码的基础权限，同时实现了页面组件和接口的颗粒度权限控制，开人人员更多的精力去实现业务服务开发。</p> <h2 id="系统权限图"><a href="#系统权限图" class="header-anchor">#</a> 系统权限图</h2> <ul><li>前端基于Vue3.0、Vite、 Ant-Design-Vue、TypeScript，权限模型自主设计。</li></ul> <div class="custom-block tip"><p class="custom-block-title">提示</p> <p>请参考 Vben Admin官网文档，地址：<a href="https://doc.vvbin.cn/" target="_blank" rel="noopener noreferrer">Vben Admin<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></div> <ul><li>用户管理（增删改查）
<img src="/turbo-cloud-blog/assets/img/ums/turbo-cloud-user.png" alt="turbo-cloud-user"></li> <li>角色管理（增删改查），角色和权限多对多
<img src="/turbo-cloud-blog/assets/img/ums/turbo-cloud-role.png" alt="turbo-cloud-role"></li> <li>权限管理（增删改查），权限和菜单、权限和组件、权限和接口
<img src="/turbo-cloud-blog/assets/img/ums/turbo-cloud-permission.png" alt="turbo-cloud-role"></li> <li>菜单管理（增删改查），菜单和组件、菜单和接口
<img src="/turbo-cloud-blog/assets/img/ums/turbo-cloud-menu.png" alt="turbo-cloud-menu"></li> <li>部门管理（增删改查）
<img src="/turbo-cloud-blog/assets/img/ums/turbo-cloud-dept.png" alt="turbo-cloud-dept"></li> <li>修改密码（增删改查）
<img src="/turbo-cloud-blog/assets/img/ums/turbo-cloud-pwd.png" alt="turbo-cloud-pwd"></li></ul> <h2 id="用户角色设计"><a href="#用户角色设计" class="header-anchor">#</a> 用户角色设计</h2> <ul><li>用户：成功认证并登录系统的操作员。（主体who，系统的账号、钥匙）</li> <li>角色：权限的集合，也是用户和权限之间的桥梁。</li> <li>权限：访问资源的许可，含有页面权限、操作权限和数据权限。（how）</li></ul> <blockquote><p>页面权限即模块权限，对于后台管理系统最左端的菜单栏。代表着用户可操作的模块有哪些。
操作权限即对资源的增删改查的权限，代表着用户是否可以操作（增删改查）该资源。
数据权限即数据隔离，A和B两个用户都拥有相同的权限，但是A不能查询B的隐私，B也不能查询A的隐私。即对数据进行了隔离。</p></blockquote> <ul><li>资源：引入这第四个概念，包括系统菜单、页面、按钮等（what）</li></ul> <img alt="RBAC权限模型(用户、角色、权限)" src="/turbo-cloud-blog/assets/img/rbac-model.png" style="width:600px;"> <img alt="RBAC权限模型(权限、菜单、组件|接口)" src="/turbo-cloud-blog/assets/img/rbac-permission-model.png" style="width:600px;"> <img alt="RBAC权限模型(菜单、组件|接口)" src="/turbo-cloud-blog/assets/img/rbac-menu-model.png" style="width:400px;"> <h2 id="接口权限设计"><a href="#接口权限设计" class="header-anchor">#</a> 接口权限设计</h2> <ul><li>登录验证成功服务返回<code>JWT Token</code>返回给Vue前端，Vue前端发起请求需要再http请求（Request）header的<code>Authorization</code>里面携带<code>JWT Token</code>回来；<code>JWT Token</code>存在<code>roleIds</code>集合，在<code>Gateway</code>网关服务解析<code>JWT Token</code>获取<code>roleIds</code>和<code>Redis</code>服务的接口关联的<code>roleIds</code>进行比较，如果<code>roleId</code>比较存在说明有接口访问权限并放行接口。</li></ul> <p><img src="/turbo-cloud-blog/assets/img/api-permission-flow.png" alt="api-permission-flow"></p> <div class="language-java line-numbers-mode"><pre class="language-java"><code><span class="token comment">/**
 * 接口地址权限验证
 *
 * @author zhangluning
 */</span>
<span class="token annotation punctuation">@Slf4j</span>
<span class="token annotation punctuation">@RequiredArgsConstructor</span>
<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ApiAuthLogic</span> <span class="token punctuation">{</span>

    <span class="token keyword">final</span> <span class="token class-name">UmsReactiveWebService</span> umsReactiveWebService<span class="token punctuation">;</span>
    <span class="token keyword">final</span> <span class="token class-name">JwtProperties</span> jwtProperties<span class="token punctuation">;</span>
    <span class="token keyword">final</span> <span class="token class-name">AuthProperties</span> authProperties<span class="token punctuation">;</span>
    <span class="token keyword">final</span> <span class="token class-name">RedisUtil</span> redisUtil<span class="token punctuation">;</span>

    <span class="token comment">/**
     * 验证Interface段接口秘钥
     *
     * @param request 请求
     */</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">validatePermission</span><span class="token punctuation">(</span><span class="token class-name">ServerHttpRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>authProperties<span class="token punctuation">.</span><span class="token function">getApiAuth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getEnabled</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token class-name">String</span> path <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getPath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">PathUtil</span><span class="token punctuation">.</span><span class="token function">isOpenApi</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token class-name">String</span> tokenHead <span class="token operator">=</span> jwtProperties<span class="token punctuation">.</span><span class="token function">getTokenHead</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">String</span> secret <span class="token operator">=</span> jwtProperties<span class="token punctuation">.</span><span class="token function">getSecret</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token class-name">String</span> authorization <span class="token operator">=</span> request<span class="token punctuation">.</span><span class="token function">getHeaders</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getFirst</span><span class="token punctuation">(</span><span class="token class-name">HttpHeaders</span><span class="token punctuation">.</span>AUTHORIZATION<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">StrUtil</span><span class="token punctuation">.</span><span class="token function">isBlank</span><span class="token punctuation">(</span>authorization<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>authorization<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span>tokenHead<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
            <span class="token comment">// The part after &quot;Bearer &quot; 有个空格</span>
            <span class="token class-name">String</span> authToken <span class="token operator">=</span> authorization<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span>tokenHead<span class="token punctuation">.</span><span class="token function">length</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">JwtPayload</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">AdminUser</span><span class="token punctuation">&gt;</span></span> jwtPayload <span class="token operator">=</span> <span class="token class-name">JwtUtils</span><span class="token punctuation">.</span><span class="token function">getUserInfoFromToken</span><span class="token punctuation">(</span>authToken<span class="token punctuation">,</span> secret<span class="token punctuation">,</span> <span class="token class-name">AdminUser</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">AdminUser</span> adminUser <span class="token operator">=</span> jwtPayload<span class="token punctuation">.</span><span class="token function">getUserInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">Objects</span><span class="token punctuation">.</span><span class="token function">isNull</span><span class="token punctuation">(</span>adminUser<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>adminUser<span class="token punctuation">.</span><span class="token function">getPermissionIds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>

            <span class="token class-name">String</span> cacheKey <span class="token operator">=</span> <span class="token class-name">GatewayConstants</span><span class="token punctuation">.</span>REDIS_KEY_API_PERMISSION_PREFIX <span class="token operator">+</span> path<span class="token punctuation">;</span>
            <span class="token comment">// 缓存5分钟有效期</span>
            <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> cacheApiPermissionsList <span class="token operator">=</span> <span class="token class-name">CaffeineCacheUtil</span><span class="token punctuation">.</span><span class="token function">getApiCache</span><span class="token punctuation">(</span>cacheKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>cacheApiPermissionsList<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token class-name">String</span> permissionIdsJson <span class="token operator">=</span> redisUtil<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>cacheKey<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">StrUtil</span><span class="token punctuation">.</span><span class="token function">isNotBlank</span><span class="token punctuation">(</span>permissionIdsJson<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    cacheApiPermissionsList <span class="token operator">=</span> JSON<span class="token punctuation">.</span><span class="token function">parseArray</span><span class="token punctuation">(</span>permissionIdsJson<span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token comment">// 防止缓存穿透</span>
                    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>cacheApiPermissionsList<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                        cacheApiPermissionsList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>
                    <span class="token class-name">CaffeineCacheUtil</span><span class="token punctuation">.</span><span class="token function">setApiCache</span><span class="token punctuation">(</span>cacheKey<span class="token punctuation">,</span> cacheApiPermissionsList<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">return</span> <span class="token function">hasPermission</span><span class="token punctuation">(</span>cacheApiPermissionsList<span class="token punctuation">,</span> adminUser<span class="token punctuation">.</span><span class="token function">getPermissionIds</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    <span class="token comment">/**
     * 是否有权限
     *
     * @param cacheApiPermissionsList 缓存的接口权限ID集合
     * @param userPermissionList      用户的接口权限ID集合
     * @return 是否有效
     */</span>
    <span class="token keyword">private</span> <span class="token keyword">boolean</span> <span class="token function">hasPermission</span><span class="token punctuation">(</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> cacheApiPermissionsList<span class="token punctuation">,</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> userPermissionList<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>cacheApiPermissionsList<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>userPermissionList<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">String</span> userRoleId <span class="token operator">:</span> userPermissionList<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>cacheApiPermissionsList<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span>userRoleId<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br><span class="line-number">71</span><br><span class="line-number">72</span><br><span class="line-number">73</span><br><span class="line-number">74</span><br><span class="line-number">75</span><br><span class="line-number">76</span><br><span class="line-number">77</span><br><span class="line-number">78</span><br><span class="line-number">79</span><br><span class="line-number">80</span><br><span class="line-number">81</span><br><span class="line-number">82</span><br><span class="line-number">83</span><br><span class="line-number">84</span><br></div></div><h2 id="数据库表"><a href="#数据库表" class="header-anchor">#</a> 数据库表</h2> <ul><li>使用了Mysql数据库。</li></ul> <h2 id="数据库表关系模型"><a href="#数据库表关系模型" class="header-anchor">#</a> 数据库表关系模型</h2> <p><img src="/turbo-cloud-blog/assets/img/db/db-ums-design.png" alt="turbo-cloud-design"></p> <h2 id="数据库脚本"><a href="#数据库脚本" class="header-anchor">#</a> 数据库脚本</h2> <ul><li>创建数据库、表、索引和初始化数据。</li></ul> <p><a href="/turbo-cloud-blog/assets/file/db/ums_db.sql">数据库SQL</a></p></div></div>  <div class="page-edit"><!----> <!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2023/05/30, 16:03:14</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/turbo-cloud-blog/pages/bab2db/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">系统登录</div></a> <!----></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/turbo-cloud-blog/pages/bab2db/" class="prev">系统登录</a></span> <!----></p></div></div></div> <!----></main></div> <div class="footer"><div class="icons"><a href="https://gitee.com/aquarian-bottle" title="GitHub" target="_blank" class="iconfont icon-github"></a><a href="https://gitee.com/aquarian-bottle" title="Gitee" target="_blank" class="iconfont icon-gitee"></a><a href="864314760@qq.com" title="发邮件" target="_blank" class="iconfont icon-youjian"></a></div> 
  Theme by
  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> 
    | Copyright © 2016-2023
    <span><a href="https://gitee.com/aquarian-bottle" target="_blank" style="font-weight:bold">Team Aquarius</a> | Sponsored by <a href="https://www.jetbrains.com" target="_blank" style="font-weight:bold">JetBrains</a> | <a href="https://gitee.com/aquarian-bottle/" target=_blank>粤ICP备12009483号</a><p>友情链接：<a href="https://www.baomidou.com/" target="_blank" style="font-weight:bold">MybatisPlus</a> | <a href="https://www.macrozheng.com/" target="_blank" style="font-weight:bold">MacroZheng</a> | <a href="https://doc.vvbin.cn/" target="_blank" style="font-weight:bold">VbenAdmin</a> | <a href="https://www.antdv.com/" target="_blank" style="font-weight:bold">AntDesignVue</a></p></span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
          跟随系统
        </li><li class="iconfont icon-rijianmoshi">
          浅色模式
        </li><li class="iconfont icon-yejianmoshi">
          深色模式
        </li><li class="iconfont icon-yuedu">
          阅读模式
        </li></ul></div></div> <!----> <!----> <div class="custom-html-window custom-html-window-rb" style="display:;"><div class="custom-wrapper"><span class="close-but">×</span> <div>
    <ins class="adsbygoogle"
    style="display:block"
    data-ad-client="ca-pub-4147143076931995"
    data-ad-slot="1866407052"
    data-ad-format="auto"
    data-full-width-responsive="true"></ins>
    <script>
        (adsbygoogle = window.adsbygoogle || []).push({});
    </script>
  </div></div></div></div><div class="global-ui"></div></div>
    <script src="/turbo-cloud-blog/assets/js/app.fa1a75e5.js" defer></script><script src="/turbo-cloud-blog/assets/js/2.5e61b679.js" defer></script><script src="/turbo-cloud-blog/assets/js/9.47d98ce3.js" defer></script>
  </body>
</html>
